package com.autumn.redis;

import java.net.UnknownHostException;

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import com.autumn.spring.boot.properties.SpringRedisProperties;

/**
 * 启用 AutumnRedis 配置
 * 
 * @author 老码农
 *
 *         2018-01-14 15:09:05
 */
@Configuration
@EnableConfigurationProperties({ SpringRedisProperties.class })
public class AutumnRedisConfiguration {

	/**
	 * 默认 Redis 连接工厂 Bean 名称
	 */
	public final static String REDIS_CONNECTION_FACTORY_BEAN_NAME = "redisConnectionFactory";

	public final static String REDIS_TEMPLATE_BEAN_NAME = "redisTemplate";

	//	public final static String AUTUMN_REDIS_TEMPLATE_BEAN_NAME = "autumnRedisTemplate";
	
	/**
	 * 
	 * @author 老码农
	 *
	 *         2017-12-19 15:37:13
	 */
	@Configuration
	@ConditionalOnClass(GenericObjectPool.class)
	protected static class AutumnRedisBeanConfiguration {
		private final RedisConnectionFactoryBuild factoryBuild;

		/**
		 * 
		 * @param properties
		 * @param sentinelConfiguration
		 * @param clusterConfiguration
		 */
		public AutumnRedisBeanConfiguration(SpringRedisProperties properties,
				ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
				ObjectProvider<RedisClusterConfiguration> clusterConfiguration) {
			this.factoryBuild = new RedisConnectionFactoryBuild(properties, sentinelConfiguration,
					clusterConfiguration);
		}

		@Bean(REDIS_CONNECTION_FACTORY_BEAN_NAME)
		@Primary
		@ConditionalOnMissingBean(name = REDIS_CONNECTION_FACTORY_BEAN_NAME)
		public JedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
			return this.factoryBuild.createConnectionFactory();
		}
		
		@Bean(REDIS_TEMPLATE_BEAN_NAME)
		@Primary
		@ConditionalOnMissingBean(name = REDIS_TEMPLATE_BEAN_NAME)
		public RedisTemplate<Object, Object> redisTemplate(
				@Qualifier(REDIS_CONNECTION_FACTORY_BEAN_NAME) RedisConnectionFactory redisConnectionFactory)
				throws UnknownHostException {
			RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
			template.setConnectionFactory(redisConnectionFactory);
			return template;
		}

		@Bean
		@Primary
		@ConditionalOnMissingBean(StringRedisTemplate.class)
		public StringRedisTemplate stringRedisTemplate(
				@Qualifier(REDIS_CONNECTION_FACTORY_BEAN_NAME) RedisConnectionFactory redisConnectionFactory)
				throws UnknownHostException {
			StringRedisTemplate template = new StringRedisTemplate();
			template.setConnectionFactory(redisConnectionFactory);
			return template;
		}

		@Bean
		@Primary
		@ConditionalOnMissingBean(AutumnRedisTemplate.class)
		public AutumnRedisTemplate autumnRedisTemplate(
				@Qualifier(REDIS_CONNECTION_FACTORY_BEAN_NAME) RedisConnectionFactory redisConnectionFactory)
				throws UnknownHostException {
			AutumnRedisTemplate template = new AutumnRedisTemplate();
			template.setConnectionFactory(redisConnectionFactory);
			return template;
		}
	}

	
}
